import axios from 'axios'
import type { AxiosInstance, InternalAxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'
import type { RequestConfig } from './type'
import { Base64 } from 'js-base64'
import { ElMessage } from 'element-plus'
import { isHeaders, decryptCustomBase64 } from '@/utils'
 
// 拦截器: 蒙版Loading/token/修改配置

/**
 *  1.拦截器进行精细控制
 *    > 全局拦截器
 *    > 实例拦截器
 *    > 单次请求拦截器
 *
 *  2.响应结果的类型处理(泛型)
 */
const RequestEnums = {
  TIMEOUT : 20000,
  OVERDUE : 600, // 登录失效
  FAIL : 999, // 请求失败
  SUCCESS : 200, // 请求成功
}
class RequestHttp {
  instance: AxiosInstance
  // request实例 => axios的实例
  constructor(config: RequestConfig) {
    this.instance = axios.create(config)
    // 每个instance实例都添加拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // loading/token 
        if (config.data) {
          config.data = Base64.encode(config.data)
        }
        let headers = {...config.headers,...isHeaders(false)}  
        // 平台接口
        if(config.url.indexOf('.show')>0 ){ 
         headers = {...config.headers,...isHeaders(true)} 
        }
         for(const i in headers){
          config.headers[i] = headers[i]
        }
        return config
      },
      (error: AxiosError) => {
        // 请求报错
        Promise.reject(error)
       }
    )
    // 接受响应
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {  
        let { data } = response; // 解构

        if (data.code === RequestEnums.OVERDUE) {
          // 登录信息失效，应跳转到登录页面，并清空本地的token
          localStorage.setItem('token', '');
          // router.replace({
          //  path: '/login'
          // })
          return Promise.reject(data);
        }

        // 全局错误信息拦截（防止下载文件得时候返回数据流，没有code，直接报错）
        if (data.code && data.code !== RequestEnums.SUCCESS) {
          ElMessage.error(data); // 此处也可以使用组件提示报错信息
          return Promise.reject(data)
        }
        
        data = JSON.parse(decryptCustomBase64(response.data,undefined,undefined,))
        console.log(data,'---------------res.data');  
        
        return data
      },
      (error: AxiosError) => {
        if (error) { 
          console.log(error,'error');
         }
        if (!window.navigator.onLine) {
          ElMessage.error('网络连接失败');
        }
        return error
      },
     
    )
  }

  // 封装网络请求的方法
  // T => IHomeData
  request<T = any>(config: RequestConfig<T>) {
    // 单次请求的成功拦截处理
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(<InternalAxiosRequestConfig>config)
      // config = config.interceptors.requestSuccessFn(config as InternalAxiosRequestConfig)
    }

    // 返回Promise
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 单词响应的成功拦截处理
          if (config.interceptors?.responseSuccessFn) {
            res = config.interceptors.responseSuccessFn(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  get<T = any>(config: RequestConfig<T>) {
    return this.request({ ...config, method: 'GET' })
  }
  post<T = any>(config: RequestConfig<T>) {
    return this.request({ ...config, method: 'POST' })
  }
  delete<T = any>(config: RequestConfig<T>) {
    return this.request({ ...config, method: 'DELETE' })
  }
  patch<T = any>(config: RequestConfig<T>) {
    return this.request({ ...config, method: 'PATCH' })
  }
}

export default RequestHttp
